home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-05-19 | 13.9 KB | 460 lines |
- /*
- * Copyright (C) 1995 Sun Microsystems, Inc
- * All rights reserved.
- * Notice of copyright on this source code
- * product does not indicate publication.
- *
- * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by
- * the U.S. Government is subject to restrictions as set forth
- * in subparagraph (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software Clause at DFARS 252.227-7013 (Oct. 1988)
- * and FAR 52.227-19 (c) (June 1987).
- *
- * Sun Microsystems, Inc., 2550 Garcia Avenue,
- * Mountain View, California 94043.
- */
-
- /*
- * @(#) CheckersGame.java 1.4 - last change made 03/17/97
- */
-
- import java.awt.*;
- import java.applet.*;
-
- /**
- * A java implementation of checkers. Can be run either as a
- * standalone application or as an applet.
- */
- public class CheckersGame extends Applet {
- final int CHECKER_NONE = 0;
- final int CHECKER_RED = 1;
- final int CHECKER_BLACK = 2;
- final int CHECKER_RED_KING = 3;
- final int CHECKER_BLACK_KING = 4;
-
- final int SQUARE_RED = 0;
- final int SQUARE_BLACK = 1;
-
- final int squaresPerSide = 8;
- final int pixelsPerBoard = 400;
- final int pixelsPerSquare = 50;
-
- final int MOVE_INVALID = 0;
- final int MOVE_VALID = 1;
- final int MOVE_HANDLED = 2;
-
- int pieces[][] = new int [squaresPerSide][squaresPerSide];
- int board[][] = new int [squaresPerSide][squaresPerSide];
-
- Image blackChecker;
- Image redChecker;
- Image blackKingChecker;
- Image redKingChecker;
-
- int clipX = 0,
- clipY = 0,
- clipWidth = this.getSize().width,
- clipHeight = this.getSize().height;
-
- int moving_piece = CHECKER_NONE;
- int moving_piece_xpos = 0;
- int moving_piece_ypos = 0;
- int moving_piece_x = -1;
- int moving_piece_y = -1;
-
- private int sign(int value) {
- if (value > 0)
- value = 1;
- else if (value < 0)
- value = -1;
- return value;
- }
-
- private void SetUpdateRegion(int xpos, int ypos) {
- int x1, y1, x2, y2;
- int halfPixelsPerSquare = pixelsPerSquare / 2;
- Dimension d = this.getSize();
-
- x1 = Math.max(0, Math.min (xpos, moving_piece_xpos) -
- halfPixelsPerSquare);
- y1 = Math.max(0, Math.min (ypos, moving_piece_ypos) -
- halfPixelsPerSquare);
-
- x2 = Math.min(d.width-1, Math.max (xpos, moving_piece_xpos) +
- halfPixelsPerSquare);
- y2 = Math.min(d.height-1, Math.max (ypos, moving_piece_ypos) +
- halfPixelsPerSquare);
-
- clipX = x1;
- clipY = y1;
- clipWidth = x2 - x1;
- clipHeight = y2 - y1;
- }
-
- private int validMove(int piece, int oldX, int oldY, int newX, int newY) {
- int dx = newX - oldX;
- int dy = newY - oldY;
-
- // Keep the pieces on the board please!
- if (newX < 0 || newX >= squaresPerSide ||
- newY < 0 || newY >= squaresPerSide)
- return MOVE_INVALID;
-
- // We play on black squares only!
- if (board[newY][newX] == SQUARE_RED)
- return MOVE_INVALID;
-
- // Can't move to a square that's already occupied.
- if (pieces[newY][newX] != CHECKER_NONE)
- return MOVE_INVALID;
-
- switch (piece) {
- default:
- case CHECKER_NONE:
- return MOVE_INVALID;
-
- case CHECKER_RED:
- // Red pieces can only go forward, positive dy's
- if (dy < 1)
- return MOVE_INVALID;
-
- // Is this a valid one square move.
- if (Math.abs(dx) == 1 && dy == 1) {
- // When we reach the other end of the board,
- // we get kinged.
- if (newY == (squaresPerSide - 1)) {
- pieces[newY][newX] = CHECKER_RED_KING;
- return MOVE_HANDLED;
- } else {
- return MOVE_VALID;
- }
- }
-
- // Is this a valid jump?
- if (Math.abs(dx) == 2 && dy == 2) {
- // A two square move must be over an opposiing player
- if (pieces[oldY+1][oldX+sign(dx)] != CHECKER_BLACK &&
- pieces[oldY+1][oldX+sign(dx)] != CHECKER_BLACK_KING)
- return MOVE_INVALID;
-
- // take the opposing player's piece off the board.
- pieces[oldY+1][oldX+sign(dx)] = CHECKER_NONE;
-
- // When we reach the other end of the board,
- // we get kinged.
- if (newY == (squaresPerSide - 1)) {
- pieces[newY][newX] = CHECKER_RED_KING;
- return MOVE_HANDLED;
- }
-
- return MOVE_VALID;
- }
- break;
- case CHECKER_BLACK:
- // Black pieces can only go forward, negative dy's
- if (dy > -1)
- return MOVE_INVALID;
-
- // Is this a valid one square move.
- if (Math.abs(dx) == 1 && dy == -1) {
- // When we reach the other end of the board,
- // we get kinged.
- if (newY == 0) {
- pieces[newY][newX] = CHECKER_BLACK_KING;
- return MOVE_HANDLED;
- } else {
- return MOVE_VALID;
- }
- }
-
- // Is this a valid jump?
- if (Math.abs(dx) == 2 && dy == -2) {
- // A two square move must be over an opposiing player
- if (pieces[oldY-1][oldX+sign(dx)] != CHECKER_RED &&
- pieces[oldY-1][oldX+sign(dx)] != CHECKER_RED_KING)
- return MOVE_INVALID;
-
- // take the opposing player's piece off the board.
- pieces[oldY-1][oldX+sign(dx)] = CHECKER_NONE;
-
- // When we reach the other end of the board,
- // we get kinged.
- if (newY == 0) {
- pieces[newY][newX] = CHECKER_BLACK_KING;
- return MOVE_HANDLED;
- }
- return MOVE_VALID;
- }
- break;
- case CHECKER_RED_KING:
- if (Math.abs(dx) == 1 && Math.abs(dy) == 1) {
- return MOVE_VALID;
- }
-
- if (Math.abs(dx) == 2 && Math.abs(dy) == 2) {
- if (pieces[oldY+sign(dy)][oldX+sign(dx)] == CHECKER_BLACK) {
- pieces[oldY+sign(dy)][oldX+sign(dx)] = CHECKER_NONE;
- return MOVE_VALID;
- } else if (pieces[oldY+sign(dy)][oldX+sign(dx)] ==
- CHECKER_BLACK_KING) {
- pieces[oldY+sign(dy)][oldX+sign(dx)] = CHECKER_NONE;
- return MOVE_VALID;
- } else {
- return MOVE_INVALID;
- }
- }
- break;
- case CHECKER_BLACK_KING:
- if (Math.abs(dx) == 1 && Math.abs(dy) == 1) {
- return MOVE_VALID;
- }
-
- if (Math.abs(dx) == 2 && Math.abs(dy) == 2) {
- if (pieces[oldY+sign(dy)][oldX+sign(dx)] == CHECKER_RED) {
- pieces[oldY+sign(dy)][oldX+sign(dx)] = CHECKER_NONE;
- return MOVE_VALID;
- } else if (pieces[oldY+sign(dy)][oldX+sign(dx)] ==
- CHECKER_RED_KING) {
- pieces[oldY+sign(dy)][oldX+sign(dx)] = CHECKER_NONE;
- return MOVE_VALID;
- } else {
- return MOVE_INVALID;
- }
- }
- break;
- }
- return MOVE_INVALID;
- }
-
- /**
- * The initialization method for an applet
- */
- public void init () {
- int xcolor = 0;
- int ycolor = 0;
- int x, y;
-
- blackChecker = getImage(getCodeBase(), "blackChecker.gif");
- redChecker = getImage(getCodeBase(), "redChecker.gif");
- blackKingChecker = getImage(getCodeBase(), "blackCheckerKing.gif");
- redKingChecker = getImage(getCodeBase(), "redCheckerKing.gif");
-
- for (x=0; x < squaresPerSide; x++) {
- ycolor = xcolor % 2;
- for (y=0; y < squaresPerSide; y++) {
- board[y][x] = ((ycolor % 2) == 1) ? SQUARE_BLACK : SQUARE_RED;
- ycolor++;
- }
- xcolor++;
- }
- for (x = 0; x < squaresPerSide; x++) {
- for (y = 0; y < squaresPerSide; y++) {
- pieces[y][x] = CHECKER_NONE;
- }
- }
- for (y = 0; y < 3; y++) {
- for (x = 1 - (y % 2); x < squaresPerSide; x=x+2) {
- pieces[y][x] = CHECKER_RED;
- }
- }
- for (y = squaresPerSide - 3; y < squaresPerSide; y++) {
- for (x = 1 - (y % 2); x < squaresPerSide; x=x+2) {
- pieces[y][x] = CHECKER_BLACK;
- }
- }
- resize(pixelsPerBoard, pixelsPerBoard);
- }
-
- /**
- * draws the checkerboard
- * @param g the graphics object
- */
- public void paint(Graphics g) {
- int xpos, ypos, x, y;
- Color redColor = Color.red;
- Color blackColor = Color.black;
- Dimension d = this.getSize();
-
- for (x=0; x < squaresPerSide; x++) {
- for (y=0; y < squaresPerSide; y++) {
- switch (board[y][x]) {
- case SQUARE_RED:
- g.setColor(redColor);
- break;
- default:
- g.setColor(blackColor);
- break;
- }
- xpos = x * pixelsPerSquare;
- ypos = y * pixelsPerSquare;
- g.fillRect (xpos, ypos, pixelsPerSquare, pixelsPerSquare);
- }
- }
-
- for (x=0; x < squaresPerSide; x++) {
- for (y=0; y < squaresPerSide; y++) {
- xpos = x * pixelsPerSquare;
- ypos = y * pixelsPerSquare;
- switch (pieces[y][x]) {
- case CHECKER_NONE:
- break;
- case CHECKER_RED:
- g.drawImage(redChecker, xpos, ypos, this);
- break;
- case CHECKER_BLACK:
- g.drawImage(blackChecker, xpos, ypos, this);
- break;
- case CHECKER_RED_KING:
- g.drawImage(redKingChecker, xpos, ypos, this);
- break;
- case CHECKER_BLACK_KING:
- g.drawImage(blackKingChecker, xpos, ypos, this);
- break;
- default:
- break;
- }
- }
- }
-
- xpos = moving_piece_xpos - pixelsPerSquare / 2;
- ypos = moving_piece_ypos - pixelsPerSquare / 2;
-
- switch (moving_piece) {
- case CHECKER_NONE:
- break;
- case CHECKER_RED:
- g.drawImage(redChecker, xpos, ypos, this);
- break;
- case CHECKER_BLACK:
- g.drawImage(blackChecker, xpos, ypos, this);
- break;
- case CHECKER_RED_KING:
- g.drawImage(redKingChecker, xpos, ypos, this);
- break;
- case CHECKER_BLACK_KING:
- g.drawImage(blackKingChecker, xpos, ypos, this);
- break;
- default:
- break;
- }
-
- clipX = 0;
- clipY = 0;
- clipWidth = d.width;
- clipHeight = d.height;
- }
-
- /**
- * updates the checkerboard display
- * @param g the graphics object
- */
- public void update(Graphics g) {
- g.clipRect (clipX, clipY, clipWidth, clipHeight);
- paint(g);
- }
-
- /**
- * process a mouse down event
- * @param evt the event
- * @param xpos the x coordinate of the event
- * @param ypos the y coordinate of the event
- */
- public boolean mouseDown(java.awt.Event evt, int xpos, int ypos) {
- int x = xpos / pixelsPerSquare;
- int y = ypos / pixelsPerSquare;
-
- if (x >= 0 && x < squaresPerSide &&
- y >= 0 && y < squaresPerSide) {
-
- if (pieces[y][x] != CHECKER_NONE) {
- moving_piece = pieces[y][x];
- pieces[y][x] = CHECKER_NONE;
- moving_piece_xpos = xpos;
- moving_piece_ypos = ypos;
- moving_piece_x = x;
- moving_piece_y = y;
- repaint();
- } else {
- moving_piece = CHECKER_NONE;
- }
- }
- return true;
- }
-
- /**
- * process a mouse up event
- * @param evt the event
- * @param xpos the x coordinate of the event
- * @param ypos the y coordinate of the event
- */
- public boolean mouseUp(java.awt.Event evt, int xpos, int ypos) {
- int x = xpos / pixelsPerSquare;
- int y = ypos / pixelsPerSquare;
- int moveStatus;
-
- if (moving_piece == CHECKER_NONE)
- return false;
-
- moveStatus = validMove(moving_piece, moving_piece_x, moving_piece_y,
- x, y);
- switch (moveStatus) {
- case MOVE_VALID:
- pieces[y][x] = moving_piece;
- break;
- case MOVE_INVALID:
- pieces[moving_piece_y][moving_piece_x] = moving_piece;
- break;
- case MOVE_HANDLED:
- default:
- break;
- }
- moving_piece = CHECKER_NONE;
- repaint();
-
- return true;
- }
-
- /**
- * process a mouse exit event
- */
- public void mouseExit() {
- if (moving_piece == CHECKER_NONE)
- return;
-
- pieces[moving_piece_y][moving_piece_x] = moving_piece;
- moving_piece = CHECKER_NONE;
- repaint();
- }
-
- /**
- * process a mouse drag event
- */
- public boolean mouseDrag(java.awt.Event evt, int xpos, int ypos) {
-
- if (moving_piece == CHECKER_NONE)
- return false;
-
- SetUpdateRegion(xpos, ypos);
-
- moving_piece_xpos = xpos;
- moving_piece_ypos = ypos;
-
- repaint();
- return true;
- }
-
- /*
- * The main routine for a standalone program.
- */
- public static void main(String args[]) {
- Frame f = new Frame("Checkers game");
- CheckersGame app = new CheckersGame();
- app.init();
- app.start();
-
- f.add("Center", app);
- f.setSize(300, 300);
- f.show();
- }
- }
-